home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / exec / execvp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-22  |  3.9 KB  |  170 lines

  1. /* 
  2.  * execvp.c --
  3.  *
  4.  *    Source code for the execvp library procedure.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/lib/c/exec/RCS/execvp.c,v 1.5 91/07/22 10:42:58 ouster Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <errno.h>
  23.  
  24. /*
  25.  * Library imports:
  26.  */
  27.  
  28. extern char **environ;
  29. extern execve();
  30.  
  31.  
  32. /*
  33.  *-----------------------------------------------------------------------
  34.  *
  35.  * DoExec --
  36.  *
  37.  *    Function to actually execute a program. If the exec didn't succeed
  38.  *    because the file isn't in a.out format, attempt to execute
  39.  *    it as a bourne shell script.
  40.  *
  41.  * Results:
  42.  *    None.  Doesn't even return unless the exec failed.
  43.  *
  44.  * Side Effects:
  45.  *    A program may be execed over this one.
  46.  *
  47.  *-----------------------------------------------------------------------
  48.  */
  49.  
  50. static void
  51. DoExec(file, argv)
  52.     char *file;            /* File to execute. */
  53.     char **argv;        /* Arguments to the program. */
  54. {
  55.     execve(file, argv, environ);
  56.     if (errno == ENOEXEC) {
  57.     /*
  58.      * Attempt to execute the file as a shell script using
  59.      * the Bourne shell)
  60.      */
  61.     register int i;
  62. #define MAX_ARGS 1000
  63.     char *newArgv[MAX_ARGS+1];
  64.  
  65.     for (i = 0; argv[i] != 0; i++) {
  66.         /* Empty loop body */
  67.     }
  68.     if (i >= MAX_ARGS) {
  69.         return;
  70.     }
  71.     newArgv[0] = "sh";
  72.     newArgv[1] = file;
  73.     for (i = 1; argv[i] != 0; i++) {
  74.         newArgv[i+1] = argv[i];
  75.     }
  76.     newArgv[i+1] = 0;
  77.     execve("/sprite/cmds/sh", newArgv, environ);
  78.     }
  79. }
  80.  
  81. /*
  82.  *----------------------------------------------------------------------
  83.  *
  84.  * execvp --
  85.  *
  86.  *    Execute a process, using the current environment variable,
  87.  *    instead of an explicitly-supplied one.  Also, imitate the
  88.  *    shell's actions in trying each directory in a search path
  89.  *    (given by the "PATH" environment variable).
  90.  *
  91.  * Results:
  92.  *    This procedure returns only if the exec fails.  In this case
  93.  *    the return value is -1.
  94.  *
  95.  * Side effects:
  96.  *    Overlays the current process with a new image.  See the man
  97.  *    page for details.
  98.  *
  99.  *----------------------------------------------------------------------
  100.  */
  101.  
  102. int
  103. execvp(name, argv)
  104.     char *name;            /* Name of file containing program to exec. */
  105.     char **argv;        /* Array of arguments to pass to program. */
  106. {
  107.     char *path;
  108. #define MAX_NAME_SIZE 1000
  109.     char fullName[MAX_NAME_SIZE+1];
  110.     register char *first, *last;
  111.     int nameLength, size, noAccess;
  112.  
  113.     noAccess = 0;
  114.  
  115.     if (index(name, '/') != 0) {
  116.     /*
  117.      * If the name specifies a path, don't search for it on the search path,
  118.      * just try and execute it.
  119.      */
  120.     DoExec(name, argv);
  121.     return -1;
  122.     }
  123.  
  124.     path = getenv("PATH");
  125.     if (path == 0) {
  126.     path = "/sprite/cmds";
  127.     }
  128.     nameLength = strlen(name);
  129.     for (first = path; ; first = last+1) {
  130.  
  131.     /*
  132.      * Generate the next file name to try.
  133.      */
  134.  
  135.     for (last = first; (*last != 0) && (*last != ':'); last++) {
  136.         /* Empty loop body. */
  137.     }
  138.     size = last-first;
  139.     if ((size + nameLength + 2) >= MAX_NAME_SIZE) {
  140.         continue;
  141.     }
  142.     (void) strncpy(fullName, first, size);
  143.     if (last[-1] != '/') {
  144.         fullName[size] = '/';
  145.         size++;
  146.     }
  147.     (void) strcpy(fullName + size, name);
  148.  
  149.     DoExec(fullName, argv);
  150.     if (errno == EACCES) {
  151.         noAccess = 1;
  152.     } else if (errno != ENOENT) {
  153.         break;
  154.     }
  155.     if (*last == 0) {
  156.         /*
  157.          * Hit the end of the path. We're done.
  158.          * If there existed a file by the right name along the search path,
  159.          * but its permissions were wrong, return FS_NO_ACCESS. Else return
  160.          * whatever we just got back.
  161.          */
  162.         if (noAccess) {
  163.         errno = EACCES;
  164.         }
  165.         break;
  166.     }
  167.     }
  168.     return -1;
  169. }
  170.